// TestServer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Client.h"
#include <conio.h>

VOID ProcessPacket( net::INetPacket* pPacket );
extern net::PacketProtocal ProtocalCustom;
extern void ConsoleTest();
int _tmain(int argc, _TCHAR* argv[])
{
	net::CreateNetwork( net::asio );
	net::InitNetwork( 10 );

	net::IMessageQueue* mQueue = xgc_nullptr;
	xgc_long_ptr hServer = net::StartServer( "0.0.0.0", 6666, &mQueue, 0, 15000, ProtocalCustom, 10 );
	if( hServer && mQueue )
	{
		while( mQueue )
		{
			net::INetPacket* pPacket = mQueue->PopMessage();
			if( pPacket )
			{
				ProcessPacket( pPacket );
				pPacket->release();
			}
			else
			{
				Sleep(1);
			}
		}

		net::CloseServer( hServer );
		mQueue->Release();
	}
	net::FiniNetwork();
	net::DestroyNetwork();
	return 0;
}

void ProcessAccept( net::network_t h )
{
	net::Param_SetUserdata _set;
	_set.handle = h;
	_set.userdata_ptr = reinterpret_cast<xgc_lpvoid>( new CClient() );
	net::ExecuteState( Operator_SetUserdata, (xgc_long_ptr) &_set );
}

void ProcessClose( net::network_t h, xgc_lpvoid userdata )
{
	CClient* pClient = reinterpret_cast< CClient* >( userdata );
	SAFE_DELETE(pClient);
}

void ProcessError( net::network_t h, int e )
{
	net::CloseLink( h );
}

VOID ProcessPacket( net::INetPacket* pPacket )
{
	bufstream buf( pPacket->data(), pPacket->size() );
	xgc_uint16 length;
	xgc_byte type, code;
	buf >> length >> type >> code;
	switch( type )
	{
	case SYSTEM_MESSAGE_TYPE:
		switch( code )
		{
		case EVENT_ACCEPT:
			ProcessAccept( pPacket->handle() );
			break;
		case EVENT_CLOSE:
			ProcessClose( pPacket->handle(), pPacket->userdata() );
			break;
		case EVENT_ERROR:
			ProcessError( pPacket->handle(), *(int*)buf.rd_ptr() );
			break;
		}
		break;
	default:
		{
			net::SendPacket( pPacket->handle(), pPacket->data(), pPacket->size() );
		}
	}
}